/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package utility;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.WritableComparable;

/**
 *
 * @author takeshi
 *
 * only support Integer , Float , Double , boolean, Byte, or Text
 */
// To do : refer to   ObjectWritable
//To Do : binary comparator
public class PairT<T> implements WritableComparable<T> {

    private T first;
    private T second;

    public PairT() {
    }

    public PairT(T first, T second) {
        this.first = first;
        this.second = second;
    }

//    public PairT(Integer first, T second) {
//        this.first = (T)first;
//        this.second = second;
//    }

    public void set(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        return second;
    }

    public void write(DataOutput out) throws IOException {
        if (this.first instanceof Integer) {
            out.writeInt((Integer) first);
        } else if (this.first instanceof Long) {
            out.writeLong((Long) first);
        } else if (this.first instanceof Float) {
            out.writeFloat((Float) first);
        } else if (this.first instanceof Double) {
            out.writeDouble((Double) first);
        } else if (this.first instanceof Boolean) {
            out.writeBoolean((Boolean) first);
        }

    }

    @Override
    public String toString() {
        return   first  + "\t " + second  ;
    }


    public void readFields(DataInput in) throws IOException {
        if (this.first instanceof Integer) {
            first = (T) Integer.valueOf(in.readInt()) ;
            second = (T) Integer.valueOf(in.readInt());
        }else if(this.first instanceof Double){
            first = (T) Double.valueOf(in.readDouble()) ;
            second = (T) Double.valueOf(in.readDouble());
        }else if (this.first instanceof Float){
             first = (T) Float.valueOf(in.readFloat()) ;
            second = (T) Float.valueOf(in.readFloat());
        }

    }

    @Override
    public boolean equals(Object o) {
        if (getClass() != o.getClass()) {
            return false;
        }
        PairT<T> ip = (PairT<T>) o;
        return first == ip.first && second == ip.second;
    }


    @Override
    public int hashCode() {
        return ((Integer) first * 163 + (Integer) second);
    }

    @Override
    public int compareTo(T ip) {
        int cmp = compare(first, ( (PairT<T>)ip).first);
        if (cmp != 0) {
            return cmp;
        }
        return compare(second, ( (PairT<T>)ip).second);
    }

    /**
     * Convenience method for comparing two T (int,float,double).
     */
    public static  int compare(Object a, Object b) {
        return ((Double)a < (Double)b ? -1 : ((Double)a == (Double)b ? 0 : 1));
    }
 
  
}
